package com.onerway.api.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.onerway.common.Signable;
import com.onerway.config.OnerWayConfig;
import com.onerway.entity.OnerWayResponse;
import com.onerway.entity.settle.SettlementFile;
import com.onerway.enums.EndpointEnum;
import com.onerway.util.SignUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
public class TransactionHelper {


    public OnerWayConfig onerWayConfig;

    public static final String SUCCESS_CODE = "20000";

    public TransactionHelper(OnerWayConfig onerWayConfig) {
        this.onerWayConfig = onerWayConfig;
    }

    public static boolean isSuccess(OnerWayResponse<?> onerwayResponse) {
        return SUCCESS_CODE.equals(onerwayResponse.getRespCode());
    }

    public <T> OnerWayResponse<T> doTransaction(Signable reqBodySignable, EndpointEnum EndpointEnum, TypeReference<OnerWayResponse<T>> typeReference) throws IOException {
        reqBodySignable.setSign(SignUtil.sign(reqBodySignable, onerWayConfig.getSecret()));

        String url = onerWayConfig.getDomain() + EndpointEnum.getEndpoint();

        String transactionBody = JSON.toJSONString(reqBodySignable);

        log.info("\n 请求地址: {}\n 请求负载: {}", url, transactionBody);

        OkHttpClient client = new OkHttpClient().newBuilder()
                .connectTimeout(20, java.util.concurrent.TimeUnit.SECONDS)
                .readTimeout(20, java.util.concurrent.TimeUnit.SECONDS)
                .build();
        MediaType mediaType = MediaType.parse("application/json");

        RequestBody body = RequestBody.create(mediaType, transactionBody);
        Request request = new Request.Builder()
                .url(url)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "*/*")
                .addHeader("Host", "sandbox-acq.onerway.com")
                .addHeader("Connection", "keep-alive")
                .build();

        try (Response response = client.newCall(request).execute()) {
            assert response.body() != null;

            String resBody = response.body().string();

            log.info("\n 响应结果: {}", resBody);

            return JSON.parseObject(resBody, typeReference);
        }
    }


    public byte[] download(SettlementFile settlementFile, EndpointEnum EndpointEnum) throws IOException {
        String url = onerWayConfig.getDomain() + EndpointEnum.getEndpoint();

        log.info("\n 请求地址: {}\n 请求负载: {}", url, settlementFile);

        OkHttpClient client = new OkHttpClient().newBuilder()
                .connectTimeout(20, java.util.concurrent.TimeUnit.SECONDS)
                .readTimeout(20, java.util.concurrent.TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "*/*")
                .addHeader("Host", "sandbox-acq.onerway.com")
                .addHeader("Connection", "keep-alive")
                .addHeader("merchantNo", settlementFile.getMerchantNo())
                .addHeader("date", settlementFile.getDate())
                .addHeader("currency", settlementFile.getCurrency())
                .addHeader("sign", settlementFile.getSign())
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Failed to download file: " + response);
            }

            try (InputStream inputStream = response.body().byteStream();
                 ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                byte[] buffer = new byte[2048];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
                return outputStream.toByteArray();
            }
        }

    }


}
